import os
import re
import csv
import shutil
import logging

# 配置日志
logging.basicConfig(
    level=logging.INFO, 
    format='%(asctime)s - %(levelname)s - %(message)s',
    handlers=[logging.FileHandler('simplified_dat_processor.log'), logging.StreamHandler()]
)
logger = logging.getLogger(__name__)

def extract_device_info(content):
    """从文件内容中提取品牌、型号和UID信息"""
    brand = None
    model = None
    uid = None
    
    # 提取品牌信息（支持带引号/不带引号，冒号/等号分隔）
    brand_match = re.search(r'ro\.product\.brand["\']?\s*[:=]\s*["\']?([^\s,}]+)', content)
    # 提取型号信息（同上）
    model_match = re.search(r'ro\.product\.model["\']?\s*[:=]\s*["\']?([^\s,}]+)', content)
    # 提取UID信息（支持通用UID格式）
    uid_match = re.search(r'uid["\']?\s*[:=]\s*["\']?([^\s,}]+)', content)
    
    if brand_match:
        brand = brand_match.group(1).strip('"\'')  # 移除可能的引号
    if model_match:
        model = model_match.group(1).strip('"\'')
    if uid_match:
        uid = uid_match.group(1).strip('"\'')
    
    return brand, model, uid  # 返回三个值

def collect_dat_files(root_dir="data_2"):
    """遍历目录收集所有DAT文件"""
    dat_files = []
    if not os.path.exists(root_dir):
        logger.warning(f"创建目录: {root_dir}")
        os.makedirs(root_dir, exist_ok=True)
    
    for dirpath, _, filenames in os.walk(root_dir):
        for filename in filenames:
            if filename.lower().endswith('.dat'):
                dat_files.append(os.path.abspath(os.path.join(dirpath, filename)))
    
    logger.info(f"找到 {len(dat_files)} 个DAT文件")
    return dat_files

def parse_dat_file_simplified(file_path):
    """简化版DAT文件解析器（仅使用extract_device_info方法）"""
    result = {'brand': None, 'model': None, 'uid': None, 'file_path': file_path}
    
    # 尝试多种编码读取文件内容
    encodings = ['utf-8', 'gbk', 'latin-1']
    content = None
    for encoding in encodings:
        try:
            with open(file_path, 'r', encoding=encoding) as f:
                content = f.read()  # 读取完整内容
            break
        except Exception as e:
            continue  # 尝试下一种编码
    
    if content:
        # 直接使用老板提供的提取方法
        brand, model, uid = extract_device_info(content)
        result.update({'brand': brand, 'model': model, 'uid': uid})
    else:
        logger.warning(f"无法读取文件内容: {file_path}")
    
    return result

def generate_csv_report(parsed_results, csv_path="simplified_device_info.csv"):
    """生成简化版CSV报告"""
    with open(csv_path, 'w', newline='', encoding='utf-8') as f:
        writer = csv.DictWriter(f, fieldnames=['品牌', '型号', 'UID', '文件路径'])
        writer.writeheader()
        for item in parsed_results:
            writer.writerow({
                '品牌': item['brand'] or '',
                '型号': item['model'] or '',
                'UID': item['uid'] or '',
                '文件路径': item['file_path']
            })
    logger.info(f"CSV报告生成: {os.path.abspath(csv_path)}")

    def sanitize_folder_name(name):
     """清理文件夹名称，移除Windows非法字符"""
    if not name:
        return "UnknownModel"
    # 移除Windows系统中的非法字符
    illegal_chars = r'[\\/:*?"<>|]'
    sanitized = re.sub(illegal_chars, '_', name)
    # 移除首尾空白字符并限制长度
    return sanitized.strip()[:50] or "UnknownModel"

def load_device_info(csv_path="simplified_device_info.csv"):
    """从CSV文件加载设备信息（品牌、型号、文件路径）"""
    device_info = {}
    
    try:
        if not os.path.exists(csv_path):
            logger.error(f"CSV文件不存在: {csv_path}")
            return {}
            
        with open(csv_path, 'r', encoding='utf-8') as f:
            reader = csv.DictReader(f)
            for row in reader:
                file_path = row['文件路径']
                brand = row['品牌'].strip()
                model = row['型号'].strip()
                
                if file_path and brand and model:  # 只处理品牌和型号都存在的记录
                    device_info[file_path] = {
                        'brand': brand,
                        'model': model,
                        'file_name': os.path.basename(file_path)
                    }
        
        logger.info(f"成功加载 {len(device_info)} 条设备信息")
        return device_info
        
    except Exception as e:
        logger.error(f"加载设备信息失败: {str(e)}")
        return {}

def classify_by_model():
    """在品牌文件夹内按型号创建子文件夹并移动文件"""
    # 1. 加载设备信息
    device_info = load_device_info()
    if not device_info:
        logger.error("没有可处理的设备信息，程序退出")
        return False
    
    stats = {
        'total_files': len(device_info),
        'moved_success': 0,
        'moved_failed': 0,
        'model_folders_created': 0,
        'errors': []
    }
    
    # 2. 记录已创建的型号文件夹，避免重复计数
    created_model_folders = set()
    
    # 3. 遍历所有设备信息，按型号分类文件
    for file_path, info in device_info.items():
        brand = info['brand']
        model = info['model']
        file_name = info['file_name']
        
        # 构建路径
        brand_folder = sanitize_folder_name(brand)
        model_name = sanitize_folder_name(model)
        model_folder = os.path.join(brand_folder, model_name)
        src_path = os.path.join(brand_folder, file_name)  # 品牌文件夹中的文件路径
        
        # 检查源文件是否存在（可能已被移动过）
        if not os.path.exists(src_path):
            # 如果品牌文件夹中不存在，尝试使用原始路径
            src_path = file_path
            if not os.path.exists(src_path):
                error_msg = f"文件不存在: {src_path}"
                logger.error(error_msg)
                stats['errors'].append(error_msg)
                stats['moved_failed'] += 1
                continue
        
        try:
            # 创建型号文件夹
            if not os.path.exists(model_folder):
                os.makedirs(model_folder, exist_ok=True)
                created_model_folders.add(model_folder)
                stats['model_folders_created'] += 1
                logger.info(f"创建型号文件夹: {model_folder}")
            
            # 目标路径
            dst_path = os.path.join(model_folder, file_name)
            
            # 移动文件（如果目标文件不存在）
            if not os.path.exists(dst_path):
                shutil.move(src_path, dst_path)
                stats['moved_success'] += 1
                logger.debug(f"移动成功: {src_path} -> {dst_path}")
            else:
                logger.warning(f"目标文件已存在，跳过: {dst_path}")
                stats['moved_failed'] += 1
                
        except Exception as e:
            error_msg = f"处理文件 {file_name} 失败: {str(e)}"
            logger.error(error_msg)
            stats['errors'].append(error_msg)
            stats['moved_failed'] += 1
    
    # 4. 输出结果统计
    logger.info("\n======= 型号分类处理完成 =======")
    logger.info(f"总文件数: {stats['total_files']}")
    logger.info(f"成功移动: {stats['moved_success']}")
    logger.info(f"移动失败: {stats['moved_failed']}")
    logger.info(f"创建型号文件夹: {stats['model_folders_created']}")
    logger.info(f"型号分类成功率: {stats['moved_success']/stats['total_files']:.2%}")
    logger.info("===============================")
    
    set_result(
        status="success" if stats['moved_failed'] == 0 else "partial_success",
        message="型号分类处理完成",
        stats=stats
    )
    
    return True

if __name__ == "__main__":
    classify_by_model()